"""
面试相关路由 - 核心业务逻辑
"""

import json
import logging
import traceback
from uuid import UUID
from typing import List, Optional

from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File, Form
from fastapi.responses import StreamingResponse
from sqlalchemy.orm import Session

from app.auth import get_current_user
from app.database import get_db
from app.models import User, Position, InterviewSession, ChatMessage
from app.schemas import (
    InterviewSessionResponse,
    ChatRequest,
    AnalyzeRequest,
    MessageResponse,
)
from app.redis_client import ChatHistoryCache
from app.rag import InterviewAgent, AnalysisAgent
from app.resume_parser import ResumeParser

router = APIRouter(prefix="/api/interview", tags=["面试"])

# 配置日志
logger = logging.getLogger(__name__)


@router.post(
    "/start",
    response_model=InterviewSessionResponse,
    status_code=status.HTTP_201_CREATED,
)
async def start_interview(
    position_id: str = Form(..., description="岗位ID"),
    cv_text: Optional[str] = Form(None, description="简历文本（与文件上传二选一）"),
    cv_file: Optional[UploadFile] = File(None, description="简历文件（与文本二选一）"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """
    创建面试会话（支持文本输入或文件上传）

    支持两种方式提供简历：
    1. 直接提供 cv_text（文本形式）
    2. 上传 cv_file（文件形式，支持 PDF、DOCX、DOC、TXT、MD等格式）

    Args:
        position_id: 岗位 ID
        cv_text: 简历文本内容（可选）
        cv_file: 简历文件（可选）
        db: 数据库会话
        current_user: 当前用户

    Returns:
        InterviewSessionResponse: 创建的会话信息

    Raises:
        HTTPException: 岗位不存在、简历信息缺失或文件解析失败时抛出异常
    """
    # 记录接收到的参数
    logger.info("=" * 80)
    logger.info(f"[Start Interview] 用户 {current_user.username} 创建面试会话")
    logger.info(f"岗位ID: {position_id}")
    logger.info(f"cv_text 是否提供: {cv_text is not None}")
    logger.info(f"cv_file 是否提供: {cv_file is not None}")
    if cv_file:
        logger.info(f"文件名: {cv_file.filename}")
        logger.info(f"文件类型: {cv_file.content_type}")
    logger.info("=" * 80)

    # 验证必须提供简历文本或文件之一
    if not cv_text and not cv_file:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="必须提供简历文本（cv_text）或简历文件（cv_file）",
        )

    if cv_text and cv_file:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="只能提供简历文本或简历文件中的一种，不能同时提供",
        )

    # 如果上传了文件，解析文件内容
    if cv_file:
        cv_text = await ResumeParser.parse_resume(cv_file)

    # 转换 position_id 为 UUID
    try:
        from uuid import UUID as UUIDType

        position_uuid = UUIDType(position_id)
    except ValueError:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, detail="岗位ID格式错误"
        )

    # 验证岗位是否存在
    position = db.query(Position).filter(Position.position_id == position_uuid).first()

    if not position:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="岗位不存在")

    # 创建新会话
    new_session = InterviewSession(
        user_id=current_user.user_id,
        position_id=position_uuid,
        cv_text=cv_text,
    )

    db.add(new_session)
    db.commit()
    db.refresh(new_session)

    # 创建初始问候消息
    initial_message_content = (
        f"您好！欢迎参加{position.title}岗位的面试。\n\n"
        "我是您的AI面试官，接下来我会基于您的简历和岗位要求进行一对一的面试交流。\n\n"
        "面试过程中，请您如实回答问题，展示您的专业能力和项目经验。准备好了吗？让我们开始吧！\n\n"
        "首先，能否请您简单介绍一下自己和您最擅长的技术领域？"
    )

    # 保存初始消息到数据库
    initial_message = ChatMessage(
        session_id=new_session.session_id,
        role="ai",
        content=initial_message_content,
    )
    db.add(initial_message)
    db.commit()

    # 将初始消息加入 Redis 缓存
    ChatHistoryCache.append_message(
        new_session.session_id, "ai", initial_message_content
    )

    logger.info(f"[Start Interview] 已为会话 {new_session.session_id} 创建初始问候消息")

    # 构造响应，包含初始消息
    response = InterviewSessionResponse(
        session_id=new_session.session_id,
        user_id=new_session.user_id,
        position_id=new_session.position_id,
        is_ended=new_session.is_ended,
        created_at=new_session.created_at,
        initial_message=initial_message_content,
    )

    return response


@router.post("/chat")
def chat(
    chat_data: ChatRequest,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """
    核心 RAG 对话接口（流式 + 主动 Agent RAG）

    流式返回 AI 回复，提供实时响应体验。
    返回格式：Server-Sent Events (SSE)，每个 chunk 以 "data: " 开头

    Args:
        chat_data: 聊天请求数据（包含 session_id 和 message）
        db: 数据库会话
        current_user: 当前用户

    Returns:
        StreamingResponse: 流式 AI 回复

    Raises:
        HTTPException: 会话不存在或无权访问时抛出异常
    """
    # [安全检查] - 验证会话所有权
    session = (
        db.query(InterviewSession)
        .filter(InterviewSession.session_id == chat_data.session_id)
        .first()
    )

    if not session:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="会话不存在")

    if session.user_id != current_user.user_id:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN, detail="无权访问此会话"
        )

    # [面试状态检查] - 如果面试已结束，拒绝继续对话
    if session.is_ended:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, detail="面试已结束，无法继续对话"
        )

    # [快速结束判断] - 检测候选人明确的结束意图，避免不必要的 LLM 调用
    end_keywords = [
        "可以结束了",
        "结束面试",
        "再见",
    ]
    user_message_lower = chat_data.message.strip().lower()

    # 如果用户消息很短且包含结束关键词，直接结束面试
    if len(chat_data.message.strip()) < 20 and any(
        keyword in user_message_lower for keyword in end_keywords
    ):

        def quick_end():
            """快速结束面试，不调用大模型"""
            try:
                # 生成结束回复
                end_response = "非常感谢你今天的参与！我们会在 3-5 个工作日内通过邮件通知你面试结果。祝你一切顺利！"

                # 流式返回结束消息
                for char in end_response:
                    yield f"data: {json.dumps({'chunk': char}, ensure_ascii=False)}\n\n"

                # 保存消息到数据库
                user_msg = ChatMessage(
                    session_id=chat_data.session_id,
                    role="human",
                    content=chat_data.message,
                )
                db.add(user_msg)

                ai_msg = ChatMessage(
                    session_id=chat_data.session_id,
                    role="ai",
                    content=end_response,
                )
                db.add(ai_msg)

                # 标记面试结束
                session.is_ended = True
                db.commit()

                # 更新缓存
                ChatHistoryCache.append_message(
                    chat_data.session_id, "human", chat_data.message, is_internal=False
                )
                ChatHistoryCache.append_message(
                    chat_data.session_id, "ai", end_response, is_internal=False
                )

                # 发送完成信号
                done_message = {"done": True, "interview_finished": True}
                yield f"data: {json.dumps(done_message, ensure_ascii=False)}\n\n"

            except Exception as e:
                logger.error(f"快速结束面试时出错: {str(e)}")
                error_message = {"error": str(e)}
                yield f"data: {json.dumps(error_message, ensure_ascii=False)}\n\n"

        return StreamingResponse(quick_end(), media_type="text/event-stream")

    # [加载历史 - Cache] - 尝试从 Redis 获取（包含工具消息）
    chat_history = ChatHistoryCache.get(chat_data.session_id)

    # [加载历史 - DB] - Redis 未命中，从数据库加载（包含工具消息）
    if chat_history is None:
        messages = (
            db.query(ChatMessage)
            .filter(ChatMessage.session_id == chat_data.session_id)
            .order_by(ChatMessage.timestamp)
            .all()
        )

        # 加载所有消息，包括工具消息
        chat_history = [
            {
                "role": msg.role,
                "content": msg.content,
                "tool_name": msg.tool_name,  # 包含工具名称
                "is_internal": msg.is_internal,  # 包含内部标记
            }
            for msg in messages
        ]

    # [加载上下文 - DB] - 加载简历和岗位信息
    position = session.position
    cv_text = session.cv_text  # 候选人简历
    jd_text = position.jd_text  # 岗位描述
    white_paper_tag = position.white_paper_tag  # 岗位标签（用于 RAG 元数据过滤）

    # [调用 Agent + 主动 RAG] - 使用 RAG Agent（流式）
    # Agent 会根据候选人回答的内容，自主决定是否调用 RAG 工具检索白皮书知识
    # 提示词中已明确要求：不能透露白皮书内容给候选人
    agent = InterviewAgent(
        cv_text=cv_text, jd_text=jd_text, position_tag=white_paper_tag
    )

    def generate():
        """生成器函数，用于流式返回"""
        content_list = []
        current_id = None
        current_content = ""
        current_role = "ai"
        current_last = False
        current_tool_calls = ""

        # ⬇⬇⬇ 状态变量现在会真正被使用 ⬇⬇⬇
        is_thinking = False

        try:
            # 流式生成 AI 回复（包含工具调用）
            for event in agent.chat_stream(
                message=chat_data.message,
                chat_history=chat_history,
            ):
                metadata = event.get("metadata")
                token = event.get("token")

                if (
                    metadata["langgraph_node"] == "model"
                    and token.chunk_position == "last"
                    and not current_last
                ):
                    current_last = True
                    if current_content.strip():
                        ### ⬇⬇⬇ 新增/修改逻辑 (第 1 部分) ⬇⬇⬇ ###
                        # 在消息结束时，判断它是否是一个内部思考消息
                        is_internal_message = current_content.strip().startswith(
                            "<思考"
                        )
                        content_list.append(
                            {
                                "role": current_role,
                                "content": current_content,
                                "is_internal": is_internal_message,  # 添加 is_internal 标记
                            }
                        )
                        ### ⬆⬆⬆ 新增/修改逻辑 ⬆⬆⬆ ###

                    if current_tool_calls:
                        content_list.append(
                            {
                                "role": "tool_call",
                                "content": json.dumps(
                                    {
                                        "name": current_tool_calls["name"],
                                        "args": current_tool_calls["args"],
                                        "tool_call_id": current_tool_calls[
                                            "tool_call_id"
                                        ],
                                    },
                                    ensure_ascii=False,
                                ),
                            }
                        )
                    current_content = ""
                    current_tool_calls = {}

                if metadata["langgraph_node"] == "tools" and token.content_blocks:
                    content_list.append(
                        {
                            "role": "tool_result",
                            "content": json.dumps(
                                {
                                    "name": token.name,
                                    "content": token.content,
                                    "tool_call_id": token.tool_call_id,
                                },
                                ensure_ascii=False,
                            ),
                        }
                    )

                if current_last and current_id == token.id:
                    pass
                if current_last and current_id != token.id:
                    current_id = token.id
                    current_last = False

                ### ⬇⬇⬇ 新增/修改逻辑 (第 2 部分) ⬇⬇⬇ ###
                # 这是处理模型文本流（AI 回答）的核心部分
                if (
                    metadata["langgraph_node"] == "model"
                    and token.content_blocks
                    and not token.tool_calls
                ):
                    # 始终将原始文本附加到 current_content 以便完整保存
                    current_content += token.content
                    current_role = "ai"
                    current_id = token.id

                    text_chunk = token.content
                    if not text_chunk:
                        continue  # 跳过空块

                    # 稳健地处理一个 chunk 中可能包含多个标签的情况
                    # 将 chunk 按 "<思考" 标签分割
                    if "<思考" in current_content:
                        is_thinking = True
                    if "</思考>" in current_content:
                        is_thinking = False
                    if not is_thinking:
                        yield f"data: {json.dumps({'chunk': token.content}, ensure_ascii=False)}\n\n"
                        continue
                    # parts = current_content.split("<思考>")
                    # for i, part in enumerate(parts):
                    #     if i > 0:  # 如果 i > 0, 说明这部分在 "<思考" 之后
                    #         is_thinking = True

                    #     # 再将这部分按 "</思考>" 标签分割
                    #     sub_parts = part.split("</思考>")
                    #     for j, sub_part in enumerate(sub_parts):
                    #         if j > 0:  # 如果 j > 0, 说明这部分在 "</思考>" 之后
                    #             is_thinking = False

                    #         # 只有当我们 *不* 处于思考状态，并且有实际内容时，才发送给前端
                    #         if not is_thinking and sub_part:
                    #             yield f"data: {json.dumps({'chunk': token.content}, ensure_ascii=False)}\n\n"
                ### ⬆⬆⬆ 新增/修改逻辑 ⬆⬆⬆ ###

                if (
                    metadata["langgraph_node"] == "model"
                    and token.content_blocks
                    and token.tool_calls
                ):
                    # (这个逻辑保持不变, 它处理的是工具调用请求, 不是思考)
                    # 我们假设 <思考> 标签只出现在 *不* 包含 tool_calls 的文本块中
                    current_tool_calls = {
                        "name": token.tool_calls[0].get("name"),
                        "args": token.tool_calls[0].get("args"),
                        "tool_call_id": token.tool_calls[0].get("id"),
                    }

            # 1. 保存用户消息 (保持不变)
            user_message = ChatMessage(
                session_id=chat_data.session_id,
                role="human",
                content=chat_data.message,
                is_internal=False,
            )
            db.add(user_message)
            ChatHistoryCache.append_message(
                chat_data.session_id, "human", chat_data.message, is_internal=False
            )

            # 2. 遍历 content_list 保存 AI 和工具消息
            for content in content_list:
                if content["role"] == "ai":
                    ### ⬇⬇⬇ 新增/修改逻辑 (第 3 部分) ⬇⬇⬇ ###
                    # 从我们之前添加的 "is_internal" 键中获取值
                    is_internal_flag = content.get("is_internal", False)

                    ai_message = ChatMessage(
                        session_id=chat_data.session_id,
                        role="ai",
                        content=content["content"],
                        is_internal=is_internal_flag,  # ⬅️ 在这里使用标记
                    )
                    db.add(ai_message)
                    ChatHistoryCache.append_message(
                        session_id=chat_data.session_id,
                        role="ai",
                        content=content["content"],
                        is_internal=is_internal_flag,  # ⬅️ 在这里使用标记
                    )
                    ### ⬆⬆⬆ 新增/修改逻辑 ⬆⬆⬆ ###

                if content["role"] == "tool_call":
                    tool_call_message = ChatMessage(
                        session_id=chat_data.session_id,
                        role="tool_call",
                        content=content["content"],
                        tool_name=json.loads(content["content"])["name"],
                        is_internal=True,  # ⬅️ 工具调用始终是内部的
                    )
                    db.add(tool_call_message)
                    ChatHistoryCache.append_message(
                        session_id=chat_data.session_id,
                        role="tool_call",
                        content=content["content"],
                        tool_name=json.loads(content["content"])["name"],
                        is_internal=True,
                    )
                if content["role"] == "tool_result":
                    tool_result_message = ChatMessage(
                        session_id=chat_data.session_id,
                        role="tool_result",
                        content=content["content"],
                        tool_name=json.loads(content["content"])["name"],
                        is_internal=True,  # ⬅️ 工具结果始终是内部的
                    )
                    db.add(tool_result_message)
                    ChatHistoryCache.append_message(
                        session_id=chat_data.session_id,
                        role="tool_result",
                        content=content["content"],
                        tool_name=json.loads(content["content"])["name"],
                        is_internal=True,
                    )

            db.commit()

            # 发送完成信号 (保持不变)
            done_message = {
                "done": True,
            }
            yield f"data: {json.dumps(done_message, ensure_ascii=False)}\n\n"

        except Exception as e:
            # 记录详细错误日志
            logger.error("=" * 80)
            logger.error(f"[Chat] 错误发生在 session_id: {chat_data.session_id}")
            logger.error(f"异常类型: {type(e).__name__}")
            logger.error(f"错误信息: {str(e)}")
            logger.error(f"用户消息: {chat_data.message}")
            logger.error("完整堆栈跟踪:")
            logger.error(traceback.format_exc())
            logger.error("=" * 80)
            db.rollback()
            # 发送错误信息
            error_message = {"error": str(e)}
            yield f"data: {json.dumps(error_message, ensure_ascii=False)}\n\n"
        finally:
            db.close()

    return StreamingResponse(
        generate(),
        media_type="text/event-stream",
        headers={
            "Cache-Control": "no-cache",
            "Connection": "keep-alive",
            "X-Accel-Buffering": "no",  # 禁用 Nginx 缓冲
        },
    )


@router.post("/analyze")
def analyze_interview(
    analyze_data: AnalyzeRequest,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """
    生成面试分析报告（流式）

    流式返回分析报告，实时显示生成进度。
    返回格式：Server-Sent Events (SSE)，每个 chunk 以 "data: " 开头

    工作流程：
    1. 安全检查 - 验证会话所有权
    2. 加载数据 - 加载完整对话和上下文
    3. 流式调用 LLM - 生成分析报告
    4. 持久化 - 保存报告到数据库
    5. 清理缓存 - 删除 Redis 缓存

    Args:
        analyze_data: 分析请求数据
        db: 数据库会话
        current_user: 当前用户

    Returns:
        StreamingResponse: 流式分析报告

    Raises:
        HTTPException: 会话不存在或无权访问时抛出异常
    """
    # [安全检查] - 验证会话所有权
    session = (
        db.query(InterviewSession)
        .filter(InterviewSession.session_id == analyze_data.session_id)
        .first()
    )

    if not session:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="会话不存在")

    if session.user_id != current_user.user_id:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN, detail="无权访问此会话"
        )

    # [面试状态检查] - 如果面试未结束，不允许生成分析报告
    if not session.is_ended:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="面试尚未结束，无法生成分析报告",
        )

    # [已有报告检查] - 如果已有分析报告，直接返回
    if session.analysis_report:

        def return_existing_report():
            """直接返回已有报告"""
            # 流式返回已有报告（为了保持接口一致性）
            yield f"data: {json.dumps({'chunk': session.analysis_report}, ensure_ascii=False)}\n\n"
            yield f"data: {json.dumps({'done': True, 'from_cache': True}, ensure_ascii=False)}\n\n"

        return StreamingResponse(
            return_existing_report(),
            media_type="text/event-stream",
            headers={
                "Cache-Control": "no-cache",
                "Connection": "keep-alive",
                "X-Accel-Buffering": "no",
            },
        )

    # [加载所有数据 - DB] - 加载完整对话和上下文
    messages = (
        db.query(ChatMessage)
        .filter(ChatMessage.session_id == analyze_data.session_id)
        .order_by(ChatMessage.timestamp)
        .all()
    )

    if not messages:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="会话中没有对话记录，无法生成分析报告",
        )

    chat_history = [{"role": msg.role, "content": msg.content} for msg in messages]

    position = session.position
    cv_text = session.cv_text
    jd_text = position.jd_text

    # [调用 LLM] - 使用分析 Agent（流式）
    analysis_agent = AnalysisAgent()

    def generate():
        """生成器函数，用于流式返回"""
        full_report = []

        try:
            # 流式生成分析报告
            for chunk in analysis_agent.analyze_stream(
                cv_text=cv_text, jd_text=jd_text, chat_history=chat_history
            ):
                full_report.append(chunk)
                # 以 SSE 格式返回
                yield f"data: {json.dumps({'chunk': chunk}, ensure_ascii=False)}\n\n"

            # [持久化 - DB] - 保存完整报告到数据库
            complete_report = "".join(full_report)
            session.analysis_report = complete_report
            db.commit()

            # [清理 - Cache] - 删除 Redis 缓存（可选）
            ChatHistoryCache.delete(analyze_data.session_id)

            # 发送完成信号
            yield f"data: {json.dumps({'done': True}, ensure_ascii=False)}\n\n"

        except Exception as e:
            # 记录详细错误日志
            logger.error("=" * 80)
            logger.error(f"[Analyze] 错误发生在 session_id: {analyze_data.session_id}")
            logger.error(f"异常类型: {type(e).__name__}")
            logger.error(f"错误信息: {str(e)}")
            logger.error(f"对话消息数: {len(messages)}")
            logger.error("完整堆栈跟踪:")
            logger.error(traceback.format_exc())
            logger.error("=" * 80)

            # 发送错误信息
            yield f"data: {json.dumps({'error': str(e)}, ensure_ascii=False)}\n\n"

    return StreamingResponse(
        generate(),
        media_type="text/event-stream",
        headers={
            "Cache-Control": "no-cache",
            "Connection": "keep-alive",
            "X-Accel-Buffering": "no",  # 禁用 Nginx 缓冲
        },
    )


@router.get("/sessions", response_model=List[InterviewSessionResponse])
def get_user_sessions(
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """
    获取用户的面试会话列表

    Args:
        skip: 跳过的记录数
        limit: 返回的最大记录数
        db: 数据库会话
        current_user: 当前用户

    Returns:
        List[InterviewSessionResponse]: 会话列表
    """
    sessions = (
        db.query(InterviewSession)
        .filter(InterviewSession.user_id == current_user.user_id)
        .order_by(InterviewSession.created_at.desc())
        .offset(skip)
        .limit(limit)
        .all()
    )

    return sessions


@router.get("/sessions/{session_id}/messages", response_model=List[MessageResponse])
def get_session_messages(
    session_id: UUID,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """
    获取会话的聊天记录（过滤内部工具消息）

    Args:
        session_id: 会话 ID
        db: 数据库会话
        current_user: 当前用户

    Returns:
        List[MessageResponse]: 消息列表（不包含工具调用等内部消息）

    Raises:
        HTTPException: 会话不存在或无权访问时抛出异常
    """
    # 验证会话所有权
    session = (
        db.query(InterviewSession)
        .filter(InterviewSession.session_id == session_id)
        .first()
    )

    if not session:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="会话不存在")

    if session.user_id != current_user.user_id:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN, detail="无权访问此会话"
        )

    # 获取消息 - 只返回非内部消息（过滤掉工具调用）
    messages = (
        db.query(ChatMessage)
        .filter(
            ChatMessage.session_id == session_id,
            ~ChatMessage.is_internal,  # 只返回非内部消息
        )
        .order_by(ChatMessage.timestamp)
        .all()
    )

    return messages


@router.post("/sessions/{session_id}/end", response_model=InterviewSessionResponse)
def end_interview(
    session_id: UUID,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """
    手动结束面试会话

    Args:
        session_id: 会话 ID
        db: 数据库会话
        current_user: 当前用户

    Returns:
        InterviewSessionResponse: 更新后的会话信息

    Raises:
        HTTPException: 会话不存在、无权访问或已结束时抛出异常
    """
    # 验证会话所有权
    session = (
        db.query(InterviewSession)
        .filter(InterviewSession.session_id == session_id)
        .first()
    )

    if not session:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="会话不存在")

    if session.user_id != current_user.user_id:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN, detail="无权访问此会话"
        )

    if session.is_ended:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, detail="面试已经结束"
        )

    # 标记面试为已结束
    session.is_ended = True
    db.commit()
    db.refresh(session)

    return session


@router.delete("/sessions/{session_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_session(
    session_id: UUID,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """
    删除面试会话

    删除指定的面试会话及其所有相关数据（聊天记录会自动级联删除）

    Args:
        session_id: 会话 ID
        db: 数据库会话
        current_user: 当前用户

    Returns:
        204 No Content: 删除成功

    Raises:
        HTTPException: 会话不存在或无权访问时抛出异常
    """
    # 验证会话所有权
    session = (
        db.query(InterviewSession)
        .filter(InterviewSession.session_id == session_id)
        .first()
    )

    if not session:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="会话不存在")

    if session.user_id != current_user.user_id:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN, detail="无权访问此会话"
        )

    # 删除会话（chat_messages 会自动级联删除）
    db.delete(session)
    db.commit()

    # 清理 Redis 缓存（如果存在）
    try:
        from app.redis_client import ChatHistoryCache

        ChatHistoryCache.delete(session_id)
    except Exception as e:
        logger.warning(f"清理 Redis 缓存失败: {str(e)}")

    # 204 No Content 不返回任何内容
    return None
